package codebreaker.cliente.conexao;

import codebreaker.protocolo.RespostaConexao;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 * Define um servidor do jogo code breaker.
 *
 * @author Rodrigo
 */
public class Servidor {
    
    private InetAddress endereco;
    private String nome;
    
    /**
     * Cria uma nova instância de Servidor
     * @param endereco Endereco do servidor
     * @param nome Nome do servidor
     */
    public Servidor(InetAddress endereco, String nome) {
	this.setEndereco(endereco);
	this.setNome(nome);
    }
    
    /**
     * Cria uma nova instância de Servidor
     * @param endereco Endereco do servidor
     * @param nome Nome do servidor
     */
    public Servidor(String endereco, String nome) throws UnknownHostException {
	this(InetAddress.getByName(endereco), nome);
    }
    
    /**
     * Cria uma nova instância de Servidor com
     * endereco local
     * @param nome Nome do servidor
     */
    public Servidor(String nome) throws UnknownHostException {
	this(InetAddress.getLocalHost(), nome);
    }
    
    /**
     * Tenta negociar conexao com o servidor
     * @param apelido Apelido do jogador
     * @return Pacote de resposta do servidor
     */
    public RespostaConexao conectar(String apelido) {
	return conectar(apelido, codebreaker.protocolo.Constantes.PORTA_NEGOCIACAO);
    }
    
    /**
     * Tenta negociar conexao com o servidor
     * @param apelido Apelido do jogador
     * @param porta Porta de conexao
     * @return Pacote de resposta do servidor
     */
    public RespostaConexao conectar(String apelido, int porta) {
	
	RespostaConexao pacote = null;
	
	try {	    
	    Socket socket = new Socket(endereco, porta);
	    
	    /* seta entrada e saida */
	    OutputStream out = socket.getOutputStream();
	    InputStream in = socket.getInputStream();
	    
	    /* envia pedido */
	    out.write(new codebreaker.protocolo.PedidoConexao(apelido).toBytes(true));
	    
	    /* recebe resposta */
	    if (in.read() == RespostaConexao.ID) {
		byte buffer[] = new byte[128];
		in.read(buffer);
		
		pacote = new RespostaConexao(buffer, false);
	    }
	} catch (IOException ex) {
	    ex.printStackTrace();
	}
	
	return pacote;
    }
    
    public String toString() {
	return getNome();
    }
    
    public InetAddress getEndereco() {
	return endereco;
    }
    
    public void setEndereco(InetAddress endereco) {
	this.endereco = endereco;
    }
    
    public String getNome() {
	return nome;
    }
    
    public void setNome(String nome) {
	this.nome = nome;
    }
    
}
